function varargout = BusPort(varargin)
% BUSPORT MATLAB code for BusPort.fig
%      BUSPORT, by itself, creates a new BUSPORT or raises the existing
%      singleton*.
%
%      H = BUSPORT returns the handle to a new BUSPORT or the handle to
%      the existing singleton*.
%
%      BUSPORT('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in BUSPORT.M with the given input arguments.
%
%      BUSPORT('Property','Value',...) creates a new BUSPORT or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before BusPort_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to BusPort_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help BusPort

% Last Modified by GUIDE v2.5 19-Dec-2012 20:15:12

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @BusPort_OpeningFcn, ...
                   'gui_OutputFcn',  @BusPort_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before BusPort is made visible.
function BusPort_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to BusPort (see VARARGIN)

% Choose default command line output for BusPort
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes BusPort wait for user response (see UIRESUME)
% uiwait(handles.figure1);


% --- Outputs from this function are returned to the command line.
function varargout = BusPort_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;


% --- Executes on button press in applyBtn.
function applyBtn_Callback(hObject, eventdata, handles)
% hObject    handle to applyBtn (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data = get(handles.uitable,'Data');
hblock = get(handles.hblockText,'String');
blockdata = get_param(hblock,'MaskValueString');
blockdata = eval(blockdata);
[m,n] = size(data);
DefaultDataType = dsdd('Get','Config/TargetLink','DefaultDataType');
for i=1:m
    signalparam = [];
    pos = getposition(blockdata,['output#' num2str(i)]);
    if ~isempty(data{i,2})
        signalparam = ['variable' , data(i,2)];
    else
        if ~isempty(data{i,3})
            signalparam = ['class' , data(i,3)];
        end
        if ~isempty(data{i,4})
            if ~strcmp(data{i,4},DefaultDataType)
                signalparam = [signalparam,['type' , data(i,4)]];
            end
        end
        if ~isempty(data{i,5})
            signalparam = [signalparam,['scaling' , data(i,5)]];
        else
            if ~isempty(data{i,6})
                signalparam = [signalparam,['lsb' , data(i,6)]];
            elseif ~isempty(data{i,7})
                signalparam = [signalparam,['offset' , data(i,7)]];
            end
        end
    end
    blockdata(1,pos) = {signalparam};
end
data = cell2string(blockdata);
try
    set_param(hblock,'MaskValueString',data);
catch EXCEPTION
    errordlg('write data failed! please try again!','Error')
end

% --- Executes on button press in selectBtn.
function selectBtn_Callback(hObject, eventdata, handles)
% hObject    handle to selectBtn (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
hblock = gcb;
set(handles.hblockText,'String',hblock);
try
    MaskType = get_param(hblock,'MaskType');
    if strcmp(MaskType,'TL_BusOutport') || strcmp(MaskType,'TL_Inport')
        blockData = get_param(hblock,'MaskValueString');
        blockData = eval(blockData);
    else
        errordlg('the block is not a BusInport or BusOutport!','Error')
        return;
    end
catch EXCTPTION
    errordlg(['the block is not a BusInport or BusOutport!' char(10) EXCTPTION],'Error')
    return;
end

pos = getposition(blockData,'signals');
signals = blockData{1,pos}{1,1}{1,2};
% get signal name 
signalname = getsignalname(signals,'');
data = [];
m = size(signalname,1);
DefaultDataType = dsdd('Get','Config/TargetLink','DefaultDataType');
for i = 1:m
    data{i,1} = signalname{i,1};
    param.variable = [];
    param.class = [];
    param.type = DefaultDataType;
    param.scaling = [];
    param.lsb = '1';
    param.offset = '0';
    s = getparam(i,blockData);
    [m] = size(s,1);
    for j = 1:m
        if ~isempty(s{j,1})
            param.(s{j,1}) = (s{j,2});
        end
    end
    data{i,2} = param.variable;
    if ~isempty(param.variable)
        VariablePath = ['/Pool/Variables/' param.variable ];
        data{i,3} = dsdd('Get',VariablePath,'Class');
        data{i,4} = dsdd('Get',VariablePath,'Type');
        data{i,5} = dsdd('Get',VariablePath,'Scaling');        
    else
        data{i,3} = param.class;
        data{i,4} = param.type;
        data{i,5} = param.scaling;
    end
    if strcmp(param.scaling,'./LocalScaling')
        ScalingPath = ['/Pool/Variables/' param.variable '/LocalScaling'];
        data{i,6} = dsdd('Get',[ScalingPath '.LSB']);
        data{i,7} = dsdd('Get',[ScalingPath '.Offset']);
%         unit = dsdd('Get',[ScalingPath '.Unit']);
    else
        data{i,6} = param.lsb;
        data{i,7} = param.offset;
    end    
end
set(handles.uitable,'Data',data);

function position = getposition(blockData,colum)
position = '';
n = size(blockData,2);
for i=1:n
    if strcmp(blockData{1,i},colum)
        position = i + 1;
%         retrun position;
    end
end

function s = getparam(signalid,blockdata)
pos = getposition(blockdata,['output#' num2str(signalid)]);
if ~isempty(pos)
    n = size(blockdata{1,pos},2);
    s = [];
    for i = 1:2:n
        f{i,1} = blockdata{1,pos}{1,i};
        c{i,1} = blockdata{1,pos}{1,i+1};
    end
else
    f = {''};
    c = {''};
end
s = [f,c];

function signalname = getsignalname(blockdata,signalname)
[m,n] = size(blockdata);
for i = 1:m
    if n == 2
        if iscell(blockdata{i,2})
            signalname = getsignalname(blockdata{i,2},signalname);
        end
    elseif iscell(blockdata{i,1})
        signalname = getsignalname(blockdata{i,1},signalname);
    else
        if isempty(signalname)
            signalname = {blockdata{i,1}} ;
        else
            signalname = [signalname;blockdata{i,1}];
        end
    end
end


% --- Executes on button press in clearBtn.
function clearBtn_Callback(hObject, eventdata, handles)
% hObject    handle to clearBtn (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
set(handles.uitable,'Data','');

% --- Executes when selected cell(s) is changed in uitable.
function uitable_CellSelectionCallback(hObject, eventdata, handles)
% hObject    handle to uitable (see GCBO)
% eventdata  structure with the following fields (see UITABLE)
%	Indices: row and column indices of the cell(s) currently selecteds
% handles    structure with handles and user data (see GUIDATA)
Data = get(handles.uitable,'Data');

if ~isempty(eventdata.Indices)
    switch(num2str(eventdata.Indices(1,2)))
        case '2'
            objectKind = 'Variable';
        case '3'
            objectKind = 'VariableClass';
            if ~isempty(Data{eventdata.Indices(1,1),2})
                msgbox('Can not be modified!','Notes')
                return;
            end
        case '4'
            objectKind = 'Typedef';
            if ~isempty(Data{eventdata.Indices(1,1),2})
                msgbox('Can not be modified!','Notes')
                return;
            end
        case '5'
            objectKind = 'Scaling';
            if ~isempty(Data{eventdata.Indices(1,1),2})
                msgbox('Can not be modified!','Notes')
                return;
            end
        otherwise
            if ~isempty(Data{eventdata.Indices(1,1),5})
                msgbox('Can not be modified!','Notes')
                return;
            end
%             if ~isempty(Data{eventdata.Indices(1,2),2})
%                 msgbox('Can not be modified!','Notes')
%                 return;
%             end
    end
    [currentPath,bModified] = dsdd('SelectObject','currentPath', Data{eventdata.Indices(1,1),eventdata.Indices(1,2)}, 'objectKind',objectKind);
    if bModified
        switch(num2str(eventdata.Indices(1,2)))
            case '2'
                Data{eventdata.Indices(1,1),eventdata.Indices(1,2)} = currentPath;
                VariablePath = ['/Pool/Variables/' currentPath ];
                Data{eventdata.Indices(1,1),eventdata.Indices(1,2)+1} = dsdd('Get',VariablePath,'Class');
                Data{eventdata.Indices(1,1),eventdata.Indices(1,2)+2} = dsdd('Get',VariablePath,'Type');
                Data{eventdata.Indices(1,1),eventdata.Indices(1,2)+3} = dsdd('Get',VariablePath,'Scaling');
                if strcmp(Data{eventdata.Indices(1,1),eventdata.Indices(1,2)+3},'./LocalScaling')
                    ScalingPath = ['/Pool/Variables/' currentPath '/LocalScaling'];
                    Data{eventdata.Indices(1,1),eventdata.Indices(1,2)+4} = dsdd('Get',[ScalingPath '.LSB']);
                    Data{eventdata.Indices(1,1),eventdata.Indices(1,2)+5} = dsdd('Get',[ScalingPath '.Offset']);
                elseif ~isempty(Data{eventdata.Indices(1,1),eventdata.Indices(1,2)+3})
                    ScalingPath = ['/Pool/Variables/' Data{eventdata.Indices(1,1),eventdata.Indices(1,2)+3} '/LocalScaling'];
                    Data{eventdata.Indices(1,1),eventdata.Indices(1,2)+4} = dsdd('Get',[ScalingPath '.LSB']);
                    Data{eventdata.Indices(1,1),eventdata.Indices(1,2)+5} = dsdd('Get',[ScalingPath '.Offset']);
                end
            case '5'
                if isempty(Data{eventdata.Indices(1,1),2})                    
                    Data{eventdata.Indices(1,1),2} = currentPath;
                    ScalingPath = ['/Pool/Variables/' currentPath ];
                    Data{eventdata.Indices(1,1),eventdata.Indices(1,2)+1} = dsdd('Get',[ScalingPath '.LSB']);
                    Data{eventdata.Indices(1,1),eventdata.Indices(1,2)+2} = dsdd('Get',[ScalingPath '.Offset']);
                end
            otherwise
                if isempty(Data{eventdata.Indices(1,2),2})
                    Data{eventdata.Indices(1,1),2} = currentPath;
                end
        end
       set(handles.uitable,'Data',Data);
    end
end


% --- Executes on button press in aboutBtn.
function aboutBtn_Callback(hObject, eventdata, handles)
% hObject    handle to aboutBtn (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
msgbox(['Author: Xiaobiao Huang ' char(10) ...
        'Email: huangxb0512@yahoo.com' char(10) ...
        'Company: Xiaobiao Studio'],'About');



function hblockText_Callback(hObject, eventdata, handles)
% hObject    handle to hblockText (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of hblockText as text
%        str2double(get(hObject,'String')) returns contents of hblockText as a double


% --- Executes during object creation, after setting all properties.
function hblockText_CreateFcn(hObject, eventdata, handles)
% hObject    handle to hblockText (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function cellstring = cell2string(var)
%CELL2STRING get the sentence which the input cell variable created
%   cellstring = cell2string(var) get the sentence which var created
%   the input variable var must be a cell
%
%   Example:
%
%   See also STRUCT2STRING.

%   Copyright 2012-2020 Xibiao Studio
%   Author: Xiaobiao Huang
%   $Revision: 1.0.0.0 Date: $ 2012-12-18 21:32 $

if ~iscell(var)
    disp('Error: the intput variable is not a cell')
    return;
end
cellstring = [];
[f,v] = size(var);
for i=1:f
     for j=1:v
        cellstring = handlecell(cellstring,var{i,j},v,f,j,i);
        if j ~= v
            cellstring = [ cellstring ','];
        end       
     end
end
% logdata(cellstring);

function [cellstring] = handlecell(cellstring,var,cv,cf,cfPointer,cvPointer)
if ~iscell(var)
    if cfPointer == 1 && cvPointer == 1
        cellstring = [cellstring '{''' var ''''];
    else
        if strcmp(class(var),'double')
            cellstring = [cellstring '' num2str(var) ''];
        else
            if strfind(var, '')
                cellstring = [cellstring '[''' var ''']'];
            else
                cellstring = [cellstring '''' var ''''];
            end
        end
    end
else
    if cfPointer == 1 && cvPointer == 1
        cellstring = [cellstring '{'];
    end
    [f,v] = size(var);
    for i=1:f
        for j=1:v
            cellstring = handlecell(cellstring,var{i,j},v,f,j,i);
            if j ~= v
                cellstring = [ cellstring ','];
            end
        end
    end
end
if cv == 1
    if cvPointer == cv && cfPointer ~= cf  && cvPointer ~= cf
        cellstring = [ cellstring ';'];
    end
else
    if cvPointer == cv && cf > 1 && cfPointer ~= cf 
        cellstring = [ cellstring ';'];
    end
end
if cvPointer == cf && cfPointer == cv
    cellstring = [cellstring '}'];
end
